﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using Microsoft.Security.Application;

namespace InhollandAirPortal {
  public class PortalUser {
    #region parameters
    public int ID { get; private set; }
    public string code { get; private set; }
    public string voornaam { get; set; }
    public string tussenvoegsel { get; set; }
    public string achternaam { get; set; }
    public string straatnaam { get; set; }
    public int huisnummer { get; set; }
    public string huisnummer_toevoeging { get; set; }
    public string postcode { get; set; }
    public string woonplaats { get; set; }
    public string land { get; set; }
    public string telefoonnummer { get; set; }
    public int inholland_miles { get; private set; }
    public DateTime created_date { get; private set; }
    public DateTime lastlogin_date { get; private set; }
    public string passwordhash { get; private set; }
    public string loginnaam { get; set; }
    public string password { get; set; }
    public BoekingsLijst geboekte_reizen {
      get {
        return new BoekingsLijst(ID);
      }
    }

    #endregion

    public PortalUser() {
      ID = -1;
      code = String.Empty;
      voornaam = String.Empty;
      tussenvoegsel = String.Empty;
      achternaam = String.Empty;
      straatnaam = String.Empty;
      huisnummer = -1;
      huisnummer_toevoeging = String.Empty;
      postcode = String.Empty;
      woonplaats = String.Empty;
      land = String.Empty;
      telefoonnummer = String.Empty;
      inholland_miles = -1;
      created_date = DateTime.MinValue;
      lastlogin_date = DateTime.MinValue;
      passwordhash = String.Empty;
      loginnaam = String.Empty;
      password = String.Empty;
    }

		// Gebruiker ophalen uit database op basis van gebruikersnaam
    public PortalUser(string aLoginNaam)
      : this() {
      using (LoyalityDB DB = new LoyalityDB()) {
        IDataReader Reader = DB.User_GetUserByLogin(aLoginNaam);
        if (Reader.Read()) {
          Load(Reader);
        }
      }
    }

		// Gebruikers ophalen uit database op basis van userID
    public PortalUser(int aUserID)
      : this() {
      using (LoyalityDB DB = new LoyalityDB()) {
        IDataReader Reader = DB.User_GetUserByID(aUserID);
        if (Reader.Read()) {
          Load(Reader);
        }
      }
    }

    private void Load(IDataRecord ADataRecord) {
      // Waardes ophalen uit DB --> Onderaan worden deze waardes gefilterd op ongelidge tekens
      ID = LoyalityDB.GetInt32Value(ADataRecord, "id", -1);
      code = LoyalityDB.GetStringValue(ADataRecord, "code", String.Empty);
      voornaam = LoyalityDB.GetStringValue(ADataRecord, "voornaam", String.Empty);
      tussenvoegsel = LoyalityDB.GetStringValue(ADataRecord, "tussenvoegsel", String.Empty);
      achternaam = LoyalityDB.GetStringValue(ADataRecord, "achternaam", String.Empty);
      straatnaam = LoyalityDB.GetStringValue(ADataRecord, "straatnaam", String.Empty);
      huisnummer = LoyalityDB.GetInt32Value(ADataRecord, "huisnummer", -1);
      huisnummer_toevoeging = LoyalityDB.GetStringValue(ADataRecord, "huisnummer_toevoeging", String.Empty);
      postcode = Encoder.HtmlEncode(LoyalityDB.GetStringValue(ADataRecord, "postcode", String.Empty));
      woonplaats = LoyalityDB.GetStringValue(ADataRecord, "woonplaats", String.Empty);
      land = LoyalityDB.GetStringValue(ADataRecord, "land", String.Empty);
      telefoonnummer = LoyalityDB.GetStringValue(ADataRecord, "telefoonnummer", String.Empty);
      inholland_miles = LoyalityDB.GetInt32Value(ADataRecord, "inhollandmiles", -1);
      created_date = LoyalityDB.GetDateTimeValue(ADataRecord, "created", DateTime.MinValue);
      lastlogin_date = LoyalityDB.GetDateTimeValue(ADataRecord, "lastlogin", DateTime.MinValue);
      loginnaam = LoyalityDB.GetStringValue(ADataRecord, "loginnaam", String.Empty);
      passwordhash = LoyalityDB.GetStringValue(ADataRecord, "wachtwoordhash", String.Empty);
      // Ongeldige tekens uit de waardes halen
			CleanUserParameters();
    }

    public int Save() {
      // Ongeldige tekens uit de waardes halen voor het opslaan
      CleanUserParameters();

      if (ID > 0) { // Indien ID bestaat; gebruiker updaten
        return UpdateUser();
      }
			else { // Indien ID niet bestaat; nieuwe gebruiker aanmaken
        return CreateUser();
      }
    }

    private int UpdateUser() { // Gebruiker updaten 
      using (LoyalityDB DB = new LoyalityDB()) {
        return DB.User_UpdateUser(ID, voornaam, tussenvoegsel, achternaam, straatnaam, huisnummer, huisnummer_toevoeging, postcode, woonplaats, land, telefoonnummer);
      }
    }
    private int CreateUser() { // Gebruiker aanmaken
      using (LoyalityDB DB = new LoyalityDB()) {
        return DB.User_CreateUser(voornaam, tussenvoegsel, achternaam, straatnaam, huisnummer, huisnummer_toevoeging, postcode, woonplaats, land, telefoonnummer, password, loginnaam);
      }
    }

    private void CleanUserParameters() { // Ongeldige tekens uit de waardes halen
      code = Encoder.HtmlEncode(code);
      voornaam = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Letters, voornaam);
      tussenvoegsel = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Letters, tussenvoegsel);
      achternaam = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Letters, achternaam);
      straatnaam = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Letters, straatnaam);
      huisnummer_toevoeging = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Letters, huisnummer_toevoeging);
      postcode = CustomSanitize.CleanAndEncode(CustomSanitize.regex_LettersCijfers, postcode);
      woonplaats = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Letters, woonplaats);
      land = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Land,land);
      telefoonnummer = CustomSanitize.CleanAndEncode(CustomSanitize.regex_Telefoon, telefoonnummer);
      passwordhash = CustomSanitize.CleanAndEncode(CustomSanitize.regex_LettersCijfers, passwordhash);
      loginnaam = CustomSanitize.CleanAndEncode(CustomSanitize.regex_LettersCijfers, loginnaam);
    }

    public int UpdatePassword(string pNewPassword) { // Wachtwoord updaten
      if (!String.IsNullOrEmpty(pNewPassword)) {
        using (LoyalityDB DB = new LoyalityDB()) { // Wachtwoord updaten in Database
          //Stored procedure returns rowcount
          return DB.User_UpdatePasswordHash(ID, pNewPassword);
        }
      } else {
        return -1;
      }
    }
    public void UpdateLastLogin() { // Laatste login updaten
      using (LoyalityDB DB = new LoyalityDB()) {
        DB.User_UpdateLastLogin(this.ID);
      }
    }

    public static bool ValidateUser(string ALoginName, string APassword) {
      PortalUser myUser = new PortalUser(ALoginName); // User ophalen
      if (!String.IsNullOrEmpty(myUser.code)) {
        bool isvalidUser = PasswordHash.ValidatePassword(APassword, myUser.passwordhash); // Ingevoerde password hashen en vergelijken met opgeslagen hash
        if (isvalidUser) { myUser.UpdateLastLogin(); } // Laatste login updaten als de user gevalideerd is
        return isvalidUser;
      } 
			else { 
        return false;
      }
    }

    public static bool CheckAvailableLoginName(string ALoginName) { // Kijken of gebruikersnaam beschikbaar is
      using (LoyalityDB DB = new LoyalityDB()) {
        return DB.User_CheckAvailableLoginName(ALoginName);
      }
    }

    public string BoekReis(int AReisID) { // Reis boeken
      string returnmessage = string.Empty;
      if (ID > 0) {
        using (LoyalityDB DB = new LoyalityDB()) {
          returnmessage = DB.User_BoekReis(ID, AReisID);
        }
      }
      return returnmessage; // Returned een (bevestigings / mislukt )Message
    }
    public string AnnuleerBoeking(string ABoekingsCode) { // Reis annuleren
      string returnmessage = string.Empty;
      if (ID > 0) {
        using (LoyalityDB DB = new LoyalityDB()) {
          returnmessage = DB.User_AnnuleerBoeking(ID, ABoekingsCode);
        }
      }
			return returnmessage; // Returned een (bevestigings / mislukt )Message
    }
  }
}